home *** CD-ROM | disk | FTP | other *** search
/ Apple II Magazines (PO) / Nibble Volume 09, No. 08 (1988-08)(MicroSPARC)(Side A).zip / Nibble Volume 09, No. 08 (1988-08)(MicroSPARC)(Side A).po / NIBBLETERM.S < prev    next >
Text File  |  1996-12-24  |  33KB  |  1,038 lines

  1. *
  2. * NibbleTerm Source Code
  3. * for NT.OBJ1, NT.OBJ2, NT.OBJ3
  4. *
  5. * by Eric C. Mueller
  6. * Copyright(c) 1988
  7. * MicroSPARC, Inc.
  8. * Concord, MA 01742
  9. *
  10.  
  11. ORGLOC    EQU $9100      ;dec. 37120
  12.           ORG ORGLOC     ;set origin
  13.           TR ON          ;shorten printing of ASC and DS
  14.  
  15. * Jump table (offset is label...i.e. CALL BASE+3 to do TERM)
  16. :0        JMP INIT       ;initialize modem & firmware
  17. :3        JMP TERM       ;go into terminal mode
  18. :6        JMP DOBAUDCH   ;do a baud rate change
  19. :9        JMP DOSHOWT    ;toggle show on bottom
  20. :12       HEX EA,EA,EA   ;[available hook]
  21. :15       JMP DOASAVE    ;toggle autosave on/off
  22. :18       JMP DOBREAK    ;do a break send
  23. :21       JMP DODIAL     ;dial number in input buffer
  24. :24       JMP WTCNCT     ;wait for conn. after dialing
  25. :27       JMP DOBUFF     ;do a buffer call (on/off, clr)
  26. :30       JMP PRSTATUS   ;print status line
  27. :33       JMP DOHU       ;hang up phone
  28. :36       HEX EA,EA,EA   ;[available hook]
  29. :39       JMP HOLDMEM    ;mark driver memory as used
  30. :42       JMP SNDRTN     ;send out a RETURN (to abort dialing)
  31. :45       JMP DOVIEW     ;view buffer
  32. :48       JMP DORESTBM   ;restore old bitmap
  33. :51       JMP DOFLUSH    ;flush input buffer (if one exists)
  34.  
  35. * Page 3 global equates
  36. AUTOSAVE  EQU $300       ;autosave on (128) or off (0)
  37. TEMPRY    EQU $301       ;temporary character hold
  38. BUFONOFF  EQU $302       ;buffer on (128) or off (0)
  39. BAUDRT    EQU $304       ;baud rate: 0=300, 1=1200, 2=2400
  40. IDBYTE    EQU $305       ;modem driver ID: 1=IIGS, 2=SSC, 3=?
  41. SHOWFLG   EQU $306       ;show info scrollin in (0/128)
  42.  
  43. * Zero page global equates
  44. EXTPTR    EQU $06        ;(and $07) pointer to ext. interface
  45. BUFPTR    EQU $E0        ;(and $E1) pointer into buffer
  46. ZPBYTE    EQU $08        ;numbers are passed through here
  47.  
  48. * Other equates
  49. CRSR      EQU "_"        ;cursor
  50. CH        EQU $57B       ;cursor horizontal (current HT val)
  51. CV        EQU $25        ;as above but for vertical
  52. BUFST     EQU $6800      ;buffer start
  53. BUFEND    EQU ORGLOC-1   ;buffer end (driver start, too)
  54. SPKR      EQU $C030      ;make a click f/the speaker
  55. KEYBRD    EQU $C000      ;keyboard (hardware) address
  56. STROBE    EQU $C010      ;clear keyboard strobe
  57. OPNAPL    EQU $C061      ;open-apple location (>128 = pressed)
  58. WAIT      EQU $FCA8      ;wait for time in accum
  59. COUT      EQU $FDED      ;character out
  60. TABV      EQU $FB5B      ;do a VTAB
  61. BITMAP    EQU $BF58      ;ProDOS memory bitmap
  62. PBFR      EQU $0200      ;buffer for string passing
  63. MLI       EQU $BF00      ;ProDOS machine lang. interface
  64.  
  65. ********************************
  66.  
  67. DORESTBM  LDA BMS        ;has the bit map been saved
  68.           BEQ NOTSVD     ;no, don't restore it
  69.           LDY #23
  70. RESTBM1   LDA ORGBM,Y    ;restore original bit map
  71.           STA BITMAP,Y
  72.           DEY
  73.           BPL RESTBM1    ;keep going until done
  74. NOTSVD    LDA ZPBYTE     ;check zero page loc
  75.           CMP #123       ;skip modem end init?
  76.           BEQ SKIPMI     ;yes
  77.           JSR MDMEINIT   ;do closing stuff with modem
  78. SKIPMI    RTS
  79.  
  80. ********************************
  81.  
  82. DOSHOWT   LDA SHOWFLG    ;toggle show line
  83.           EOR #%10000000
  84.           STA SHOWFLG
  85.           BNE SHOWON
  86.           LDA #"-"
  87.           BNE SHOWCLR
  88. SHOWON    LDA #$A0       ;space0
  89. SHOWCLR   LDY #1         ;set show line to all spcs or dashes
  90. SHOWOFF   STA $7D0,Y
  91.           INY
  92.           CPY #38
  93.           BNE SHOWOFF    ;turn show line off
  94.           RTS
  95.  
  96. ********************************
  97.  
  98. HOLDMEM   LDY #23        ;save original bit map
  99. HOLDMEM1  LDA BITMAP,Y
  100.           STA ORGBM,Y
  101.           DEY
  102.           BPL HOLDMEM1
  103.           LDA #$01       ;yes, the bitmap has been saved
  104.           STA BMS
  105.           LDA #>BUFST    ;get high byte of address
  106. MARK      PHA
  107.           JSR DOMARK     ;mark that page as used
  108.           PLA
  109.           CMP #$9A       ;all the way out?
  110.           BEQ DONEMARK
  111.           CLC
  112.           ADC #$01
  113.           BNE MARK       ;always
  114. DONEMARK  RTS            ;return
  115.  
  116. DOMARK    TAX            ;mark page in accum. as used
  117.           LSR
  118.           LSR
  119.           LSR
  120.           TAY
  121.           TXA
  122.           AND #$07
  123.           TAX
  124.           LDA #$80
  125. DOMARK0   DEX
  126.           BMI SETBIT
  127.           LSR
  128.           JMP DOMARK0
  129. SETBIT    ORA BITMAP,Y   ;turn that bit on (mark it)
  130.           STA BITMAP,Y   ;save it
  131.           RTS
  132.  
  133. ORGBM     DS 24          ;room for original bit map
  134. BMS       DFB $00        ;bit map saved flag (t/f; 1/0)
  135.  
  136. ********************************
  137.  
  138. INIT      LDA ZPBYTE     ;prepare modem addresses
  139.           ORA #$C0
  140.           STA EXTPTR+1   ;store $Cn
  141.           ASL
  142.           ASL
  143.           ASL
  144.           ASL
  145.           STA SPEC       ;store $n0
  146.           LDA #$00
  147.           STA NOCAROFF
  148.           STA BUFONOFF   ;buffer default = off
  149.           STA AUTOSAVE   ;autosave default = off
  150.           STA EXTPTR
  151.           LDA #$80
  152.           STA SHOWFLG    ;show default = on
  153.           LDA #$01       ;default baud = 1200
  154.           STA BAUDRT
  155.           JSR RESETBUF   ;reset buffer
  156.           JSR MDMINIT    ;do modem-specific init
  157.           LDA #$00
  158.           BCC OKRTN      ;it's okay, return with no errs
  159.           LDA #$01
  160. OKRTN     STA ZPBYTE     ;indicate no error/error cond.
  161.           JSR PRSTATUS
  162.           RTS            ;done with init
  163.  
  164. SPEC      DS 1           ;equal to $n0
  165.  
  166. ********************************
  167.  
  168. DOBUFF    LDA ZPBYTE     ;get command...
  169.           BPL NORST      ;hi bit clr = don't reset it
  170.           JSR RESETBUF   ;empty buffer out
  171. NORST     LDA ZPBYTE
  172.           AND #%01111111 ;chop off high bit
  173.           BEQ RTN        ;not a buffer on/off command
  174.           JSR DOCHECK    ;check if buffer is full
  175.           BNE BUFNOTF    ;buffer not full; turn it on
  176.           JSR BUZZ0      ;buzz at 'em
  177. RTN       RTS            ;and exit
  178. BUFNOTF   LDA BUFONOFF
  179.           EOR #%10000000 ;toggle buffer on/off
  180.           STA BUFONOFF   ;and that's that!
  181.           JSR PRSTATUS   ;update status line
  182.           JMP RTN
  183.  
  184. CHKBUFST  JSR DOCHECK
  185.           BNE NOTFULL
  186.           LDA BUFONOFF   ;is buffer turned on?
  187.           BEQ NOTFULL    ;no, don't buzz
  188.           LDA #$00
  189.           STA BUFONOFF   ;turn buffer off (unconditionally)
  190.           JSR PRSTATUS   ;update status line
  191.           LDA AUTOSAVE   ;is autosave enabled?
  192.           BEQ BUZZ0      ;no, just buzz and return
  193.           SEC            ;carry set = return to basic for autosave
  194.           RTS
  195. NOTFULL   CLC
  196.           RTS
  197. BUZZ0     LDA #$20       ;buffer is full, make annoying buzz
  198.           STA REGX       ;hold length of tone
  199. BUZZ1     LDA #$02
  200.           JSR WAIT       ;wait for a short moment
  201.           STA SPKR       ;click!
  202.           LDA #$24
  203.           JSR WAIT       ;another tiny wait
  204.           STA SPKR       ;click!
  205.           DEC REGX
  206.           BNE BUZZ1
  207.           CLC            ;even though buffer is full, c=0
  208.           RTS
  209.  
  210. DOCHECK   LDA #<BUFEND
  211.           SEC
  212.           SBC BUFPTR
  213.           BNE NOTFULL0
  214.           LDA #>BUFEND
  215.           SEC
  216.           SBC BUFPTR+1
  217. NOTFULL0  RTS
  218.  
  219. RESETBUF  LDA #<BUFST    ;reset buffer to empty
  220.           STA BUFPTR
  221.           LDA #>BUFST    ;start of buffer
  222.           STA BUFPTR+1
  223.           JSR PRSTATUS
  224.           RTS
  225.  
  226. ********************************
  227.  
  228. DOASAVE   LDA AUTOSAVE
  229.           EOR #%10000000 ;toggle autosave on/off
  230.           STA AUTOSAVE
  231.           LDA ZPBYTE
  232.           AND #%01111111 ;is the high bit set (to clear, too?)
  233.           BEQ EXITAS     ;no
  234.           JSR RESETBUF   ;yes, clear buffer out
  235. EXITAS    JSR PRSTATUS
  236.           RTS
  237.  
  238. ********************************
  239.  
  240. TERM      JSR STRTFLOW   ;start input flow (ctrl-Q)
  241.           JSR CRSRON     ;print initial cursor
  242. LOOP      LDA LASTCHAR   ;get last character received
  243.           JSR CHKCARR    ;@@ EXTERNAL HOOK
  244.           BCS NOPE       ;carry set= no carrier
  245.           LDA KEYBRD     ;check for local keypress
  246.           BMI KEYHIT     ;yes, a key has been hit...
  247.           LDA OPNAPL     ;check for open-apple
  248.           BPL INPUT?     ;no, open-apple not pressed
  249.           LDA #$00       ;open apple pressed---back to basic
  250. TOBASIC   STA ZPBYTE
  251.           JSR STOPFLOW   ;stop input flow (send CTRL-S)
  252.           RTS            ;return to caller
  253. NOPE      LDA #$01       ;problem: no carrier!
  254.           BNE TOBASIC    ;return to basic
  255.  
  256. KEYHIT    BMI KEYHIT0    ;just a continuation of another branch
  257.  
  258. INPUT?    JSR CHARIN     ;@@ EXTERNAL HOOK
  259.           BCC NOKEYIN    ;no key in...
  260.           STA TEMPRY     ;hold it here for comparison
  261.           CMP #$FF       ;is it DELETE?
  262.           BEQ NOKEYIN    ;yes, ignore it
  263.           CMP #$A0
  264.           BGE OKPRT      ;if it's not a ctrl char, don't check
  265.           LDX #$00       ;start at beginning of table
  266. CHKITOUT  LDA OKAYCTRL,X ;end of table?
  267.           BEQ NOKEYIN    ;if at the end of the table, it's not okay
  268.           LDA TEMPRY     ;get comp. info
  269.           CMP OKAYCTRL,X ;is the character okay?
  270.           BEQ OKPRT      ;yes, it's okay to print
  271.           INX
  272.           BNE CHKITOUT   ;no, keep checking it
  273. OKPRT     JSR CRSROFF
  274.           JSR COUT
  275.           STA LASTCHAR   ;last character received
  276.           JSR HNDLBFR    ;handle buffer
  277.           BCC TURNCON    ;if autosave not needed, jump over
  278.           LDA #$02       ;code 2 = dump buffer (for autosave)
  279.           BNE TOBASIC    ;(always)
  280. TURNCON   JSR CRSRON
  281. GOLOOP    JMP LOOP       ;back through main term loop
  282. NOKEYIN   LDA #$00
  283.           STA LASTCHAR
  284.           BEQ GOLOOP
  285.  
  286. CRSROFF   PHA
  287.           LDA #$A0       ;erase old cursor
  288.           JSR COUT
  289.           LDA #$88
  290.           JSR COUT
  291.           PLA
  292.           RTS
  293. CRSRON    PHA
  294.           LDA #CRSR      ;put down new cursor
  295.           JSR COUT
  296.           LDA #$88
  297.           JSR COUT
  298.           PLA
  299.           RTS
  300.  
  301. KEYHIT0   BIT STROBE     ;key accepted; clear keyboard
  302.           CMP #$FF       ;delete key?
  303.           BNE STR        ;no, send whatever pressed
  304.           LDA #$88       ;yes, change to backspace
  305. STR       JSR SNDCHR     ;@@ EXTERNAL HOOK
  306.           LDA #$00       ;there wasn't really a char recvd
  307.           STA LASTCHAR
  308.           JMP LOOP       ;and back to main loop!
  309.  
  310. HNDLBFR   TAX            ;move character to x-reg
  311.           CLC
  312.           LDA BUFONOFF   ;get buffer status
  313.           BEQ BUFDONE    ;buffer is off if =0
  314.           JSR CHKBUFST   ;check buffer status
  315.           BCS BUFDONE
  316.           LDY #$00
  317.           TXA            ;grab char. back from x-reg
  318.           STA (BUFPTR),Y ;store it
  319.           INC BUFPTR
  320.           BNE NOPTROV
  321.           INC BUFPTR+1   ;increase high byte of buffer
  322. NOPTROV   JSR CHKBUFST   ;check buffer status again to be sure
  323. BUFDONE   RTS            ;return to main term loop
  324.  
  325. OKAYCTRL  DFB $80,$88,$87 ;null, bksp, bell
  326.           DFB $8D,$8A,$8C ;cr, lf, ff
  327. * add your safe control characters here!
  328.           DFB $00        ;end of table
  329. LASTCHAR  DS 1           ;last character received goes here
  330.  
  331. PRSTATUS  PHA            ;hold accum.
  332.           LDA CH
  333.           PHA
  334.           LDA CV
  335.           PHA            ;hold horiz & vertical positions
  336.           LDA #00
  337.           JSR TABV       ;VTAB 1
  338.           LDA #33        ;HTAB 34
  339.           STA CH
  340.           LDA BUFONOFF   ;get buffer status
  341.           JSR PRTONOFF   ;print out "on " or "off"
  342.           LDA #48
  343.           STA CH         ;go to next field: "Autosave:"
  344.           LDA AUTOSAVE   ;get autosave status
  345.           JSR PRTONOFF   ;print its status
  346.           LDA #62
  347.           STA CH         ;go to next field: "Baud rt:"
  348.           LDA BAUDRT     ;get baud rate
  349.           ASL            ;*2
  350.           TAY
  351.           LDA BAUDNTBL,Y
  352.           JSR COUT
  353.           LDA BAUDNTBL+1,Y
  354.           JSR COUT
  355.           PLA
  356.           JSR TABV       ;restore old vertical tab position
  357.           PLA
  358.           STA CH         ;restore old horiz. tab position
  359.           PLA            ;get accum. back
  360.           RTS
  361.  
  362. OFFONSTR  ASC 'offon '
  363. BAUDNTBL  ASC '031224'   ;the three baud rates
  364.  
  365. PRTONOFF  PHP
  366.           LDY #3
  367.           PLP
  368.           BNE PRINTON    ;value is "on" if non-zero
  369.           LDY #0
  370. PRINTON   LDX #3
  371. KEEPON    LDA OFFONSTR,Y
  372.           JSR COUT
  373.           INY            ;move pointer up
  374.           DEX            ;move counter down
  375.           BNE KEEPON     ;print all three characters
  376.           RTS
  377.  
  378. ********************************
  379.  
  380. DOHU      JMP HANGUP     ;@@ EXTERNAL HOOK
  381.  
  382. ********************************
  383.  
  384. DOVIEW    LDA #<BUFST
  385.           STA VIEW0+1
  386.           LDA #>BUFST
  387.           STA VIEW0+2
  388.           LDA BUFPTR
  389.           SEC
  390.           SBC #$01
  391.           STA ENDPT
  392.           LDA BUFPTR+1
  393.           SBC #$00
  394.           STA ENDPT+1
  395. VIEW0     LDA $FFFF      ;(self modified)
  396.           JSR COUT       ;print it
  397. DELVAL    LDX #1         ;delay loop
  398. DELVAL1   LDA #25
  399.           JSR WAIT
  400.           DEX
  401.           BNE DELVAL1
  402.           LDA KEYBRD     ;check keyboard
  403.           BPL VIEW3      ;no key, don't process
  404.           CMP #"9"+1     ;char. above nine (illegal key)?
  405.           BEQ BADKEY     ;yes, ignore it
  406.           CMP #$B0
  407.           BLT NOTSPD     ;not a speed control!
  408.           STA STROBE
  409.           AND #$0F       ;strip off top part
  410.           STA DELVAL+1
  411. NOTSPD    CMP #$A0       ;space?
  412.           BNE VIEW2      ;no, check for ESC
  413.           BIT STROBE
  414. VIEW1     LDA KEYBRD
  415.           BPL VIEW1      ;wait for another key to start
  416. BADKEY    STA STROBE
  417.           CLC
  418.           BCC VIEW3      ;always
  419. VIEW2     CMP #$9B       ;esc pressed?
  420.           BEQ EXITESC    ;yes, exit
  421.           CMP #$8D       ;return?
  422.           BEQ EXITESC    ;yes, exit
  423. VIEW3     LDA VIEW0+1    ;check low byte of offset...
  424.           CMP ENDPT      ;are they equal?
  425.           BEQ VIEW4      ;yes, check high byte
  426. INCEM     INC VIEW0+1    ;no, they're not the same
  427.           BNE GOV0       ;so just jump up the two and go
  428.           INC VIEW0+2    ;update high byte
  429. GOV0      JMP VIEW0
  430. VIEW4     LDA VIEW0+2    ;check high byte
  431.           CMP ENDPT+1    ;equal with ending point?
  432.           BNE INCEM
  433.           BIT STROBE     ;yes, exit
  434. EXITESC   RTS            ;return to basic w/key ready
  435.  
  436. ENDPT     DS 2           ;ending point for view
  437.  
  438. ********************************
  439.  
  440. DOBAUDCH  LDA ZPBYTE     ;get zero page byte from basic
  441.           STA BAUDRT     ;store new baud rate
  442.           JSR BAUDCH     ;@@ EXTERNAL HOOK
  443.           JMP PRSTATUS   ;update status and return to basic
  444.  
  445. ********************************
  446.  
  447. DOBREAK   JMP BRKSND     ;@@ EXTERNAL HOOK
  448.  
  449. ********************************
  450.  
  451. STOPFLOW  LDA #$93       ;ctrl-S (stop flow)
  452.           BNE SSPRT
  453. STRTFLOW  LDA #$91       ;ctrl-Q (start flow)
  454. SSPRT     JMP SNDCHR     ;@@ EXTERNAL HOOK
  455.  
  456.  
  457. **********************************
  458. * non-modem-specific subroutines *
  459. **********************************
  460.  
  461. * Subroutine: dial modem (number in input buffer)
  462. DODIAL    JSR DOFLUSH    ;flush buffer first
  463.           JSR DOFLUSH    ;be sure nothing else is coming
  464.           LDA #0
  465.           JSR WAIT       ;then hang on for a bit
  466.           JSR WAIT
  467.           LDY #0
  468.           LDX #4         ;send out init string
  469. DIAL1     LDA DIALINIT,Y
  470.           JSR SNDCHR     ;@@ EXTERNAL HOOK
  471.           LDA #128
  472.           JSR WAIT       ;a small inter-digit delay
  473.           INY
  474.           DEX
  475.           BNE DIAL1
  476.           LDX ZPBYTE     ;get length of number
  477.           LDY #0
  478. DIAL2     LDA PBFR,Y
  479.           JSR SNDCHR
  480.           LDA #128
  481.           JSR WAIT
  482.           INY
  483.           DEX
  484.           BNE DIAL2      ;dial entire number
  485.           LDA #$8D       ;print final return to put dial in motion
  486.           JMP SNDCHR
  487.  
  488. DIALINIT  DFB $8D,"A","T","D" ;modem dialing string
  489.  
  490. * Subroutine: flush input buffer (clear all excess garbage)
  491. DOFLUSH   JSR CHARIN     ;@@ EXTERNAL HOOK
  492.           BCS DOFLUSH    ;keep taking keys out
  493.           RTS            ;return
  494.  
  495. * Subroutine: wait for connect (or no connect) from modem
  496. WTCNCT    BIT STROBE     ;clr kbd
  497.           JSR DOFLUSH    ;flush out buffer first
  498.           LDY #5
  499.           LDA #0
  500. DEL01     JSR WAIT       ;wait for a spell
  501.           DEY
  502.           BNE DEL01
  503.           JSR DOFLUSH    ;clean out the buffer again
  504.           LDY #30
  505. WTCNCT0   LDA KEYBRD
  506.           BMI USER       ;key pressed?  get outta here.
  507.           JSR CHARIN     ;@@ EXTERNAL HOOK
  508.           BCC WTCNCT0    ;if nothing back, keep looking
  509.           CMP #"C"       ;is it "CONNECT"?
  510.           BEQ CONNECTX
  511.           CMP #"B"       ;is it "BUSY"?
  512.           BEQ UNABLE     ;yes, unable to connect
  513.           CMP #"N"       ;the "N" in "NO CARRIER" or "NO DIALTONE"?
  514.           BEQ UNABLE
  515.           DEY
  516.           BNE WTCNCT0    ;done with all chances yet?
  517. UNABLE    LDA #$00       ;;; code 0 = unable to connect
  518. RTN2      STA ZPBYTE
  519.           JSR DOFLUSH    ;flush out buffer
  520.           RTS
  521. CONNECTX  JSR CHARIN     ;wait for the final "T"
  522.           BCC CONNECTX
  523.           CMP #"T"
  524.           BNE CONNECTX
  525.           LDA #$01       ;;; code 1 = connect
  526.           BNE RTN2
  527. USER      STA ZPBYTE
  528.           BNE RTN2
  529.  
  530. * Subroutine: wait for "OK" from modem in given time.
  531. WAITOK    LDY #10        ;give modem ten chances
  532.           LDX #0         ;low byte of timeout counter
  533.           LDA #45        ;high byte of timeout counter
  534.           STA HICTR
  535. GETOK     JSR CHARIN     ;@@ EXTERNAL HOOK
  536.           BCC CTRDN      ;nothing yet, decrease counter
  537.           CMP #"K"       ;is the the "K" of "OK"?
  538.           BEQ ITISOK     ;yes, everything's good
  539.           DEY
  540.           BNE GETOK      ;keep checking for that "O"!
  541.           BEQ NOTOK      ;nope, couldn't find that "O"!
  542. ITISOK    CLC
  543.           RTS            ;carry clear = OK found
  544. NOTOK     SEC
  545.           RTS            ;carry set = OK not found
  546. CTRDN     DEX            ;move counter down
  547.           BNE GETOK      ;keep waiting
  548.           DEC HICTR      ;bump high byte of counter down
  549.           LDA HICTR
  550.           BNE GETOK      ;still doing well
  551.           BEQ NOTOK      ;nothing good in time!  exit
  552.  
  553. HICTR     DS 1           ;high byte of countdown counter for "OK"
  554.  
  555. * Subroutine: scroll character in on bottom line
  556. SHOWIT    PHA            ;scroll line in from right
  557.           LDA SHOWFLG    ;show turned on?
  558.           BEQ SHOWEND0
  559.           LDY #2
  560. SHOW1     LDA $7D0,Y
  561.           DEY
  562.           STA $7D0,Y
  563.           INY
  564.           INY
  565.           CPY #38
  566.           BNE SHOW1
  567.           PLA
  568.           DEY
  569.           AND #$7F
  570.           BPL SHOW2
  571.           CMP #'a'
  572.           BLT SHOW2
  573.           SEC
  574.           SBC #$20
  575. SHOW2     CMP #' '
  576.           BLT PUTDN
  577.           ORA #$80
  578. PUTDN     STA $7D0,Y
  579. SHOWEND   RTS
  580. SHOWEND0  PLA
  581.           RTS            ;return
  582.  
  583. * Subroutine: save registers
  584. SAVEREGS  STA REGA
  585.           STY REGY
  586.           STX REGX
  587.           RTS
  588.  
  589. * Subroutine: restore registers
  590. RESTREGS  LDA REGA
  591.           LDX REGX
  592.           LDY REGY
  593.           RTS
  594.  
  595. REGX      DS 1           ;storage for registers
  596. REGY      DS 1
  597. REGA      DS 1
  598.  
  599. * Subroutine: check for carrier (carry set=none)
  600. CHKCARR   BEQ WEHAVCAR   ;if there's no character recvd...
  601.           LDY NOCAROFF   ;get offset into NO CARRIER string
  602.           CMP NOCARR,Y   ;is it next char in "NO CARRIER"?
  603.           BEQ ANOTHER1   ;yes!  move offset up one
  604.           LDA #$00
  605.           STA NOCAROFF   ;zero offset, it's not the next one
  606. WEHAVCAR  CLC            ;we have carrier since carry is 0
  607.           RTS
  608. ANOTHER1  INC NOCAROFF   ;increase character offset
  609.           INY
  610.           CPY #11        ;is it through all eleven characters?
  611.           BNE WEHAVCAR   ;we still have carrier...for now!
  612.           LDA #$00
  613.           STA NOCAROFF
  614.           LDA #" "       ;send out a space to check for carrier
  615.           JSR SNDCHR
  616.           LDX #0         ;loop for delay
  617. DELLP     JSR CHARIN
  618.           BCC NOCHAR     ;no character yet...
  619.           BNE WEHAVCAR   ;if ANYTHING comes, it's good
  620. NOCHAR    DEX
  621.           BNE DELLP      ;we've waited long enough...
  622.           SEC            ;no carrier; carry = 1
  623.           RTS
  624. NOCARR    ASC "NO CARRIER",8D
  625. NOCAROFF  DS 1           ;offset into above string
  626.  
  627. * Subroutine: hang up telephone
  628. HANGUP    JSR STRTFLOW   ;send ctrl-Q to start input flow
  629.           LDY #11        ;wait for one second before starting
  630. HANGUP0   LDA #195
  631.           JSR WAIT
  632.           DEY
  633.           BNE HANGUP0
  634.           LDY #$03       ;send three plusses
  635. HANGUP1   LDA #"+"       ;modem into-command-mode char
  636.           JSR SNDCHR
  637.           JSR DOFLUSH    ;flush buffer around before we continue
  638.           LDX #3
  639. HANGUP2   LDA #0
  640.           JSR WAIT       ;wait for a few more milliseconds
  641.           DEX
  642.           BNE HANGUP2
  643.           DEY
  644.           BNE HANGUP1
  645.           LDX #25
  646. HANGUP3   LDA #0         ;a delay while waiting for "OK" to come
  647.           JSR WAIT
  648.           DEX
  649.           BNE HANGUP3
  650.           JSR DOFLUSH    ;empty out buffer
  651.           LDA #"A"       ;send out hangup string
  652.           JSR SNDCHR
  653.           LDA #"T"
  654.           JSR SNDCHR
  655.           LDA #"H"
  656.           JSR SNDCHR
  657.           JSR SNDRTN
  658.           LDX #3
  659. HANGUP4   LDA #0
  660.           JSR WAIT       ;and a teeny bit more delay
  661.           DEX
  662.           BNE HANGUP4    ;final wait before returning
  663.           RTS
  664.  
  665. * Subroutine: send out return ($8D)
  666. SNDRTN    LDA #$8D
  667.           JMP SNDCHR
  668.  
  669.  
  670. MDMINIT   EQU *          ;link to initial modem init
  671. MDMEINIT  EQU *+3        ;link to modem end init
  672. BRKSND    EQU *+6        ;link to send break goes here
  673. SNDCHR    EQU *+9        ;link to send character here
  674. CHARIN    EQU *+12       ;link to get character here
  675. BAUDCH    EQU *+15       ;link to change baud rate
  676.  
  677.           SAV NT.OBJ1    ;save general object
  678.  
  679. * Now we assemble the other two parts...just another handy
  680. * feature of Merlin.
  681. ENDORG    EQU *
  682.  
  683.  
  684. **                                   **
  685. ** Apple Super Serial Card (or //c)  **
  686. ** driver routines                   **
  687. **                                   **
  688.           ORG ENDORG
  689. ACTRL     EQU $C08B
  690. ACMND     EQU $C08A
  691. ASTAT     EQU $C089
  692. AXMIT     EQU $C088
  693. ARECV     EQU AXMIT
  694.  
  695. :0        JMP MDMINITR   ;links to subroutines
  696. :3        JMP MDMEINITR
  697. :6        JMP SNDBRK
  698. :9        JMP SENDCHAR
  699. :12       JMP CHARINP
  700. :15       JMP BAUDCHNG
  701.  
  702. * Subroutine: modem-specific initialization
  703. MDMINITR  LDY SPEC       ;get slot offset
  704.           LDA #$00
  705.           STA BUFRSTRT
  706.           STA BUFREND
  707.           JSR MLI        ;get interrupts rolling
  708.           DFB $40        ;ALLOC_INTERRUPT call
  709.           DA P:ALL
  710.           BCS INITPROB   ;error?  get outta here.
  711.           LDA INT_NUM    ;get interrupt number
  712.           STA INT_NUM1   ;save it for deallocate call
  713.           LDY SPEC
  714.           LDA #%00011000 ;8/1, 1200bd, int. baud gen
  715.           STA ACTRL,Y
  716.           LDA #%00001001 ;turn on xmitter & interrupts
  717.           STA ACMND,Y
  718.           CLI            ;interrupts are now live
  719.           LDA ARECV,Y    ;dump garbage
  720.           JSR SNDRTN     ;send a couple of c/rs to wake up mdm
  721.           JSR SNDRTN
  722.           JSR SNDRTN
  723.           LDY #$00
  724. MODMINIT  LDA MDMSTRI,Y
  725.           BEQ ENDSTR0
  726.           JSR SNDCHR
  727.           JSR DOFLUSH    ;get anything coming back (init string!)
  728.           LDA #150
  729.           JSR WAIT
  730.           INY
  731.           BNE MODMINIT
  732. ENDSTR0   JSR DOFLUSH
  733.           JSR WAITOK     ;wait for "OK" from modem
  734.           BCC NOINITPR
  735.           JSR WAITOK     ;wait for "OK" one more time
  736.           BCC NOINITPR
  737.           JSR WAITOK     ;wait for "OK" one more time
  738.           BCC NOINITPR
  739. INITPROB  SEC            ;no "OK" in time!
  740.           RTS
  741. NOINITPR  LDA #$02       ;store ID byte : $02 = SupSerCard or //c
  742.           STA IDBYTE
  743.           JSR SNDRTN     ;send out a return
  744.           CLC            ;clear carry = no problems
  745.           RTS            ;and that is it.  <PHEW!>  8-)
  746. * The below string specifies:
  747. * E0 don't echo back anything we type
  748. * V1 send back normal result codes
  749. * F1 don't echo anything typed (let us do the displaying)
  750. * &c track presence of DCD
  751. MDMSTRI   HEX 8D
  752.           ASC "ATZ"
  753.           HEX 8D
  754.           ASC "AT&C1E0V1F1S0=0" ;and S0=0 means don't answer phone
  755.           HEX 8D,00
  756. * Parameter tables for allocate and deallocating interrupt
  757. P:ALL     DFB $02        ;two parameters
  758. INT_NUM   DS 1           ;interrupt # is returned here
  759.           DA RDINT       ;point to interrupt handler
  760. P:DEALL   DFB $01        ;only one parameter
  761. INT_NUM1  DS 1           ;fill in interrupt number here
  762.  
  763. * Subroutine: modem end init...this is called when modem is
  764. * done being used (when program ends).  Turn buffer off here.
  765. MDMEINITR SEI            ;turn off interrupts
  766.           LDY SPEC
  767.           LDA #%00000010 ;turn interrupts & xmitter off
  768.           STA ACMND,Y
  769.           JSR MLI        ;turn off buffer
  770.           DFB $41        ;DEALLOC_INTERRUPT
  771.           DA P:DEALL
  772.           CLI            ;allow interrupts now
  773.           RTS            ;return; we're done
  774.  
  775. * Subroutine: change baud rate.  0=300, 1=1200, 2=2400
  776. BAUDCHNG  TAY
  777.           LDA #%00010000 ;8 data, one stop, int clock
  778.           ORA BAUDS,Y    ;add on bottom nybble
  779.           LDY SPEC
  780.           STA ACTRL,Y    ;set new baud rate
  781.           RTS
  782. BAUDS     DFB %00000110  ;300 baud image
  783.           DFB %00001000  ;1200 baud image
  784.           DFB %00001010  ;2400 baud image
  785.  
  786. * Subroutine: send break signal
  787. SNDBRK    LDY SPEC
  788.           LDA #%00001101 ;send a BRK
  789.           STA ACMND,Y
  790.           LDA #%00001001 ;back to normal xmitter
  791.           STA ACMND,Y
  792.           RTS
  793.  
  794. * Subroutine: get key from modem (c=1 if there; c=0 if none)
  795. CHARINP   JSR SAVEREGS
  796.           SEI            ;stop interrupts for a moment
  797.           LDY BUFRSTRT   ;get buffer start
  798.           CPY BUFREND
  799.           BEQ EXITIN     ;no character waiting
  800.           LDA IOBFR,Y    ;get the keypress
  801.           INC BUFRSTRT   ;move character pointer up
  802.           ORA #$80
  803.           CLI            ;turn interrupts back on
  804.           PHA
  805.           JSR SHOWIT     ;scroll it in
  806.           JSR RESTREGS
  807.           PLA            ;get key back
  808.           SEC            ;here's a key!
  809.           RTS            ;return
  810. EXITIN    CLI            ;turn interrupts back on
  811.           JSR RESTREGS
  812.           LDA #$00       ;no character
  813.           CLC
  814.           RTS            ;return to caller
  815.  
  816. * Subroutine: send character in accum.
  817. SENDCHAR  PHA            ;save character for a moment
  818.           JSR SAVEREGS
  819. SEND0     LDY SPEC       ;are we ready to go?
  820.           LDA ASTAT,Y
  821.           AND #%00010000
  822.           BEQ SEND0      ;we aren't ready yet
  823.           LDA #10        ;wait for a teeny moment
  824.           JSR WAIT
  825.           PLA            ;get character to send back
  826.           STA AXMIT,Y    ;send it
  827.           JSR RESTREGS
  828.           RTS            ;and return
  829.  
  830. * Special: interrupt vector for char. read
  831. RDINT     CLD            ;this is a valid handler
  832.           SEI
  833.           LDY SPEC       ;check status register
  834.           LDA ASTAT,Y
  835.           AND #%00001000 ;is the receive register full?
  836.           BEQ NOTOURS    ;no, some other interrupt popped up
  837.           LDA ARECV,Y    ;get data byte (finally!)
  838.           ORA #$80       ;set the high bit
  839.           CMP #$8A
  840.           BEQ EXITINT    ;ignore linefeed lous
  841.           CMP #$80
  842.           BEQ EXITINT    ;and nulls
  843.           LDY BUFREND
  844.           STA IOBFR,Y
  845.           INC BUFREND    ;increase length of buffer by one
  846. EXITINT   CLC            ;claim this interrupt
  847. RTNINT    CLI
  848.           RTS
  849. NOTOURS   SEC            ;not our interrupt!
  850.           BCS RTNINT     ;always
  851.  
  852. BUFRSTRT  DS 1           ;pointer to star of buffer
  853. BUFREND   DS 1           ;pointer to end of buffer
  854. IOBFR     DS 256         ;i/o buffer (a FIFO stack)
  855.  
  856.           SAV NT.OBJ2    ;save super serial object
  857.  
  858. **                                   **
  859. ** Apple IIgs modem-port specific    **
  860. ** driver routines                   **
  861. **                                   **
  862.           ORG ENDORG     ;now do second half
  863.           XC             ;the GS can handle 65c02 opcodes
  864.  
  865. :0        JMP XMDMINIT   ;specific links to subroutines
  866. :3        JMP XMDMEINIT
  867. :6        JMP XBRKSND
  868. :9        JMP XSNDCHR
  869. :12       JMP XCHARIN
  870. :15       JMP XBAUDCH
  871.  
  872. * Subroutine: modem-specific initialization
  873. XMDMINIT  LDA #$0D       ;init routine jump address
  874.           JSR DOIT
  875.           LDY #$00
  876. MDINIT0   LDA MDMISTR,Y
  877.           BEQ ENDSTR
  878.           JSR SNDCHR
  879.           INY
  880.           BNE MDINIT0
  881. ENDSTR    JSR DOFLUSH
  882.           JSR WAITOK     ;wait for "OK" from modem
  883.           BCC NOIERR
  884.           JSR WAITOK     ;wait for "OK" one more time
  885.           BCC NOIERR
  886.           JSR WAITOK     ;wait for "OK" from modem
  887.           BCC NOIERR
  888.           SEC            ;no "OK" in time!
  889.           RTS
  890. NOIERR    JSR SCA        ;wake buffering up
  891.           LDA #"B"
  892.           JSR SNDCHR
  893.           LDA #"E"
  894.           JSR SNDCHR
  895.           JSR SCA
  896.           LDA #"M"       ;mask linefeeds coming in
  897.           JSR SNDCHR
  898.           LDA #"E"
  899.           JSR SNDCHR
  900.           JSR SCA        ;set format to 8N1:
  901.           LDA #"0"       ;set data/stop bits to 8/1
  902.           JSR SNDCHR
  903.           LDA #"D"
  904.           JSR SNDCHR
  905.           JSR SCA        ;change parity to none
  906.           LDA #"0"
  907.           JSR SNDCHR
  908.           LDA #"P"
  909.           JSR SNDCHR
  910.           LDA #$01       ;store ID byte : $01 = IIGS
  911.           STA IDBYTE
  912.           JSR SNDRTN     ;send out a return
  913.           CLC            ;clear carry = no problems
  914.           RTS            ;and that is it.  <PHEW!>  8-)
  915. * The below string specifies:
  916. * E0 don't echo back anything we type
  917. * V1 send back normal result codes
  918. * F1 don't echo anything typed (let us do the displaying)
  919. MDMISTR   HEX 8D
  920.           ASC "ATZ"
  921.           HEX 8D
  922.           ASC "AT&C1E0V1F1S0=0" ;and S0=0 means don't answer phone
  923.           HEX 8D,00
  924.  
  925. * Subroutine: modem end init...this is called when modem is
  926. * done being used (when program ends).  Turn buffer off here.
  927. XMDMEINIT RTS            ;none for the GS
  928.  
  929. * Subroutine: change baud rate.  0=300, 1=1200, 2=2400
  930. XBAUDCH   PHA
  931.           LDA #"0"
  932.           STA BAUDSTR+1
  933.           PLA
  934.           BEQ DO300
  935.           DEC A
  936.           BEQ DO1200
  937.           LDA #"1"
  938.           STA BAUDSTR+1
  939.           LDA #"0"
  940.           BNE BAUDCH1
  941. DO300     LDA #"6"
  942.           BNE BAUDCH1
  943. DO1200    LDA #"8"
  944. BAUDCH1   STA BAUDSTR+2
  945.           LDY #0
  946. BAUDCH2   LDA BAUDSTR,Y
  947.           STA CHAR
  948.           STY REGY
  949.           JSR KEEPCHK    ;use special send routine for CTRL-A
  950.           LDY REGY
  951.           INY
  952.           CPY #4         ;send all four yet?
  953.           BNE BAUDCH2
  954.           RTS            ;return to caller
  955. BAUDSTR   DFB $81        ;ctrl-a
  956.           ASC "08B"      ;the 08 is changed to 06, 08, or 10
  957.  
  958. * Subroutine: send CTRL-A (modem wake-up signal)
  959. SCA       LDA #$81
  960. SCA2      STA CHAR       ;Subroutine: send ANY char in accum.
  961.           JMP KEEPCHK    ;send it and return to caller
  962.  
  963. * Subroutine: send 233-ms break signal
  964. XBRKSND   JSR SCA        ;send ctrl-A
  965.           LDA #"S"
  966.           JMP SNDCHR     ;send out the "S" to do a break
  967.  
  968. * Subroutine: get key from modem (c=1 if there; c=0 if none)
  969. XCHARIN   JSR SAVEREGS
  970.           LDA #$01
  971.           STA TEMP1
  972.           LDA #$10       ;status call
  973.           JSR DOIT       ;check if key received
  974.           BCC XIT        ;no, don't take anything, carry clr
  975.           LDA #$0E       ;read call
  976.           JSR DOIT       ;get character
  977.           ORA #$80       ;set high bit
  978.           PHA
  979.           JSR SHOWIT     ;put it into the scroll line
  980.           JSR RESTREGS
  981.           PLA
  982.           SEC            ;carry set = key available
  983.           RTS            ;return
  984. XIT       JSR RESTREGS
  985.           LDA #$00       ;no character
  986.           CLC
  987.           RTS            ;return to caller
  988.  
  989. * Subroutine: send character in accum.
  990. XSNDCHR   STA CHAR       ;save character to send
  991.           JSR SAVEREGS
  992.           CMP #$81       ;is it special control character?
  993.           BNE KEEPCHK    ;no, don't worry about it
  994.           JSR KEEPCHK    ;send CTRL-A
  995.           LDA #$82       ;change controller char to CTRL-B temp
  996.           JSR SCA2
  997.           JSR SCA        ;send control-A (really send it now)
  998.           LDA #$82
  999.           JSR SCA2       ;send controller char (CTRL-B for now)
  1000.           LDA #$81       ;and change it back to CTRL-A
  1001.           STA CHAR
  1002. KEEPCHK   LDA #$00       ;are you ready for output?
  1003.           STA TEMP1
  1004.           LDA #$10       ;status call
  1005.           JSR DOIT
  1006.           BCC KEEPCHK    ;keep checking until it's ready
  1007.           LDA CHAR
  1008.           STA TEMP1
  1009.           LDA #$0F       ;write it out
  1010.           JSR DOIT
  1011.           LDA TEMP1      ;get character
  1012.           JSR RESTREGS
  1013.           RTS            ;and return
  1014.  
  1015. CHAR      DS 1           ;character to send
  1016.  
  1017. * Subroutine: call routine via jump table for Pascal protocol.
  1018. DOIT      STA EXTPTR     ;call routine pointed to via jump addresses
  1019.           LDY #$00
  1020.           LDA (EXTPTR),Y
  1021.           SEC
  1022.           SBC #$01
  1023.           STA TEMP2
  1024.           LDA $07
  1025.           PHA
  1026.           LDA TEMP2
  1027.           PHA
  1028.           LDA TEMP1
  1029.           LDX EXTPTR+1
  1030.           LDY SPEC
  1031.           CLC
  1032.           RTS            ;call extended interface
  1033.  
  1034. TEMP1     DS 1           ;temporary storage for rtn jump pointer
  1035. TEMP2     DS 1           ;temporary storage for high byte of jmp
  1036.  
  1037.           SAV NT.OBJ3    ;save this object code, and we're done
  1038.